package com.emm.yixun.website.controller.system;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.emm.yixun.common.model.Merchant;
import com.emm.yixun.common.response.Response;
import com.emm.yixun.system.service.MerchantServiceFacade;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSONObject;
import com.emm.yixun.anotations.UserOperateLog;
import com.emm.yixun.common.enums.FunctionTypeEnum;
import com.emm.yixun.common.enums.ModelTypeEnum;
import com.emm.yixun.common.model.User;
import com.emm.yixun.common.model.enums.SsoLoginEnum;
import com.emm.yixun.common.utils.WebUtil;
import com.emm.yixun.website.common.utils.base.Const;
import com.emm.yixun.website.controller.base.BaseController;


@Controller
public class LoginController extends BaseController<Object>{
	
	
	@Value("${need.verify.code}")
	private String needVerifyCode;
	@Autowired
	private MerchantServiceFacade merchantServiceFacade;
	/**
	 * 访问登录页
	 * @return
	 */
	@RequestMapping(value="/loginIndex")
	public ModelAndView toLogin(String isReload)throws Exception{
		if(StringUtils.isBlank(isReload)){
			isReload="1";
		}
		ModelAndView mv =  new ModelAndView();
		mv.addObject("isReload",isReload);
		mv.setViewName("system/login/login");
		return mv;
	}
	
	/**
	 * 请求登录，验证用户
	 */
	@RequestMapping(value="/system_login" ,produces="application/json;charset=UTF-8")
	@ResponseBody
	@UserOperateLog(functionName=FunctionTypeEnum.FUNCTIONTYPE_11,modelName=ModelTypeEnum.MODELTYPE_4,isLogin = true)
	public Map<String, Object> login(HttpServletRequest request,String code,String username,String password)throws Exception{
		Map<String,Object> map = new HashMap<String,Object>();
		if(StringUtils.isBlank(code)){
			map.put("result", "nullcode");
			return map;
		}
		if(StringUtils.isBlank(username)||StringUtils.isBlank(password)){
			map.put("result", "nullup");//缺少用户名或密码
			return map;
		}
		//shiro管理的session
		Subject currentUser = SecurityUtils.getSubject();
		//Session session = currentUser.getSession();
		//String sessionCode = (String)session.getAttribute(Const.SESSION_SECURITY_CODE);		//获取session中的验证码	
		String sessionCode=(String)WebUtil.getSessionValue(request, Const.SESSION_SECURITY_CODE);

		if(StringUtils.isBlank(sessionCode)){
			map.put("result", "codeerror");//缺少用户名或密码
			return map;
		}
		if(StringUtils.isEmpty(needVerifyCode)
			|| "T".equals(needVerifyCode)){
			if(!sessionCode.equals(code)){
				map.put("result", "codeerror");//缺少用户名或密码
				return map;
			}
		}
		
		// shiro加入身份验证
		UsernamePasswordToken token = new UsernamePasswordToken(username, password);
		token.setRememberMe(true);
		String errInfo = "";
		try {
			User user = new User();
			Session session = currentUser.getSession();
			if(null != session){
				Object obj = session.getAttribute(Const.SESSION_USER);
				if(null != obj){
					user = (User) BeanUtils.cloneBean((User)obj);
				}
			}
			if(!username.equals(user.getUserAccount())
					&& !username.equals(user.getUserPhone())){
				currentUser.login(token);
			}else if (!currentUser.isAuthenticated()) {
				currentUser.login(token);
			}
			Object obj = session.getAttribute(Const.SESSION_USER);
			if(null != obj){
				user = (User) BeanUtils.cloneBean((User)obj);
			}

			if(null != user && null != user.getMerchantId()){
				Response<Merchant> merchantRes = merchantServiceFacade.findById(user.getMerchantId());
				if(merchantRes.isSuccess() && null != merchantRes.getEntity()){
					errInfo="success";
				}else{
					errInfo = "noMerchant";
				}
			}

		} catch (UnknownAccountException uae) {
			errInfo = "usererror";// 用户名或密码有误
		} catch (IncorrectCredentialsException ice) {
			errInfo = "usererror"; // 密码错误
		} catch (LockedAccountException lae) {
			errInfo = "inactive";// 未激活
		} catch (ExcessiveAttemptsException eae) {
			errInfo = "attemptserror";// 错误次数过多
		} catch (AuthenticationException ae) {
			errInfo = "codeerror";// 验证未通过
		}
		// 验证是否登录成功
		if (!currentUser.isAuthenticated()) {
			token.clear();
		}
		map.put("result", errInfo);
		//User user=ShiroUtil.getCurrentUser();
		//WebUtil.saveUserToken(request,username);
		return map;
	}		
	  /**
     * 帐号注销
     * @return
     */
    @RequestMapping("/system_logout")
    public String logout(HttpServletRequest request) {
        Subject currentUser = SecurityUtils.getSubject();
        currentUser.logout();
        Session session = currentUser.getSession();
        session.removeAttribute("0_user_resources_list");
        session.removeAttribute("1_user_resources_list");
        return "redirect:loginIndex.html";
    }
    
    
    /**
	 * OA单点登录
	 * @return
	 */
	@RequestMapping(value="sso/login")
	public ModelAndView ssoLogin(String username, String password, HttpServletRequest request, HttpServletResponse response){
		ModelAndView mv =  new ModelAndView("redirect:/loginIndex");
		JSONObject jsonObject = null;
		boolean loginFlag = true;
		try{
			if(StringUtils.isBlank(username)){
				jsonObject = new JSONObject();
				jsonObject.put("resCode", "10001");
				jsonObject.put("resMsg", "登录账号为空!");
				response.getWriter().write(jsonObject.toJSONString());
				loginFlag = false;
			}
			if(StringUtils.isBlank(password)){
				jsonObject = new JSONObject();
				jsonObject.put("resCode", "10002");
				jsonObject.put("resMsg", "账号密码为空!");
				response.getWriter().write(jsonObject.toJSONString());
				loginFlag = false;
			}
			// shiro管理的session
			Subject currentUser = SecurityUtils.getSubject();  
			// shiro加入身份验证
			// 拼接SSO登录名
			username = SsoLoginEnum.PREFIX.getNo() + username + SsoLoginEnum.SUFFIX.getNo();
			UsernamePasswordToken token = new UsernamePasswordToken(username, password, true);
			try {
				if (!currentUser.isAuthenticated()) {
					currentUser.login(token);
				}
			} catch (UnknownAccountException uae) {
				jsonObject = new JSONObject();
				jsonObject.put("resCode", "10003");
				jsonObject.put("resMsg", "账户名或密码错误");
				response.getWriter().write(jsonObject.toJSONString());
				loginFlag = false;
			} catch (IncorrectCredentialsException ice) {
				jsonObject = new JSONObject();
				jsonObject.put("resCode", "10003");
				jsonObject.put("resMsg", "账户名或密码错误");
				response.getWriter().write(jsonObject.toJSONString());
				loginFlag = false;
			} catch (LockedAccountException lae) {
				jsonObject = new JSONObject();
				jsonObject.put("resCode", "10004");
				jsonObject.put("resMsg", "无效账户,账户未激活");
				response.getWriter().write(jsonObject.toJSONString());
				loginFlag = false;
			} catch (ExcessiveAttemptsException eae) {
				jsonObject = new JSONObject();
				jsonObject.put("resCode", "10005");
				jsonObject.put("resMsg", "错误次数过多,请稍后重试!");
				response.getWriter().write(jsonObject.toJSONString());
				loginFlag = false;
			} catch (AuthenticationException ae) {
				jsonObject = new JSONObject();
				jsonObject.put("resCode", "10005");
				jsonObject.put("resMsg", "验证未通过");
				response.getWriter().write(jsonObject.toJSONString());
				loginFlag = false;
			}
			// 验证是否登录成功
			if (!currentUser.isAuthenticated()) {
				token.clear();
			}
		}catch(Exception ex){
			ex.printStackTrace();
			loginFlag = false;
		}finally{
			//记录请求日志
		}
		if(loginFlag){
			mv = new ModelAndView("redirect:/backstage/index");
		}
		return mv;
	}
	
}
